﻿using UnityEngine;
using System.Collections;
using System;
using System.Threading;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.ByteBuffer;
using gameplatform;
using tools;
using WindowsFormsApplication2;

using info;
using evt;
using UnityEngine.SceneManagement;

public class GSocket  : MonoBehaviour{
	
		private static Socket clientSocket;
		//private static GSocket instance;
		public static bool connectioned;
		public static bool reConnection;
		private static int prefixSize = 4;
		private static MemoryStream receiveData = new MemoryStream();
		private static bool isPresix = true;
		private static int curPrefix = 0;//需要读取的数据总长度
		
		public static bool getConnection(){
			return  clientSocket.Connected;
		}
		/*
		public static GSocket GetInstance()
		{
			if (instance == null)
			{
				instance = new GSocket();
				instance.StartSocket ();
			}
			return instance;
			
		}  	
		*/
		/**
		 * 开启SOCKET链接
	 	 */
		public static void StartSocket()
		{

			buffer = null;
			receiveData = new MemoryStream ();

			GamePlatform.deviceID = SystemInfo.deviceUniqueIdentifier;
			clientSocket = new Socket (AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
			
			//十三水外网。。。118.190.45.184、、、临时替代服务器
			//192.168.3.141
			IPAddress ipAddress = IPAddress.Parse ("192.168.3.141");
			IPEndPoint ipEndpoint = new IPEndPoint (ipAddress, 6002);
			IAsyncResult result = clientSocket.BeginConnect (ipEndpoint,new AsyncCallback (connectCallback),clientSocket);
	
			bool success = result.AsyncWaitHandle.WaitOne( 5000, true );
		     
			if ( !success )
			{
				if (SceneManager.GetActiveScene ().buildIndex == 2) {
					GameObject.Find ("assyoufuck").transform.localPosition = new Vector3(10000,10000,0);
				}
				Closed();
			} 
			else
			{
				//与socket建立连接成功，开启线程接受服务端数据。

			}
		}
		
		/**
		 *链接成功 请求加密位
	 	 */
		private static void connectCallback(IAsyncResult asyncConnect )
		{	
			Debug.Log ("asyncConnect.IsCompleted:"+asyncConnect.IsCompleted);
			 
			if (asyncConnect.IsCompleted) {
				prefixSize = 4;
				receiveData = new MemoryStream();
				isPresix = true;
				curPrefix = 0;//需要读取的数据总长度
				
				ByteTools.sendMsgCount = 0;
				connectioned = true;
				

				ReceiveSorket ();

				if (reConnection) {
					SendLogin ();
				}
	
				Heart.StopHeart = true;
			}
		}
		
		/**
		 *请求登陆
	 	 */
		public static void SendLogin(){
			if( UserInfo.OpenID != "" ){
				Debug.Log ("UserInfo.OpenID:" + UserInfo.OpenID);
				string[] str = new string[4];
				str [0] = UserInfo.OpenID;
				str [1] = UserInfo.UserData.nickName;
				str [2] = UserInfo.UserData.sex.ToString();
				str [3] = UserInfo.headUrl;
				GSocket.Send (ByteFactory.makeByte (100101, str));
			}
		}

		
		public static void ReceiveSorket()
		{
			if(clientSocket == null){
				return;
			}

			if(!connectioned){
				return;
			}
			

			try
			{    
				StateObject so = new StateObject();
				so.workSocket = clientSocket;
				//第一次读取数据的总长度
				clientSocket.BeginReceive(so.buffer,0,prefixSize,0,new AsyncCallback(receivedCallback),so);
			}
			catch(Exception e)
			{
				Debug.Log(e.ToString());
				clientSocket.Close();
			}
	  	
		}

		private static void receivedCallback(IAsyncResult ar)
    	{
	            StateObject so = (StateObject)ar.AsyncState;
	            Socket client = so.workSocket;
	            if(!client.Connected)
	            {
	                return;
	            }

	            int readSize = client.EndReceive (ar);

	            //结束读取，返回已读取的缓冲区里的字节数组长度
				
	            //将每次读取的数据，写入内存流里
				if( buffer != null ){
					buffer.PushByteArray(so.buffer);
					receiveData.Write(buffer.ToByteArray(),0,buffer.ToByteArray().Length);
					receiveData.Position = 0;
					buffer = null;
				}else{
					receiveData.Write(so.buffer,0,readSize);
					receiveData.Position = 0;
				}
	           
	            //读取前置长度，只读取一次
	            if((int)receiveData.Length >= prefixSize && isPresix)
	            {
	                byte[] presixBytes = new byte[prefixSize];
	                receiveData.Read(presixBytes,0,prefixSize);
	                Array.Reverse(presixBytes);

					curPrefix = BitConverter.ToInt32(presixBytes,0);
	                
	                isPresix = false;
	            }
	            if(receiveData.Length - (long)prefixSize < (long)curPrefix)
	            {
	                //如果数据没有读取完毕，调整Position到最后，接着读取。
	                receiveData.Position = receiveData.Length;
	            }
	            else
	            {
	                //如果内存流中的实际数字总长度符合要求，则说明数据已经全部读取完毕。
	                //将position位置调整到第4个节点，开始准备读取数据。
	                receiveData.Position = 0;
	                //读取数据
	                //byte[] datas = new byte[curPrefix+8];
	                //receiveData.Read(datas,0,datas.Length);
	                receiveDataLoad();
	            }

				if(connectioned){
					client.BeginReceive(so.buffer,0,StateObject.BufferSize,0,new AsyncCallback(receivedCallback), so);
				}
   		}

		private static ByteBuffer buffer = null;
	    private static void receiveDataLoad()
	    {
			Debug.Log ("++++++++++++++++++++++++++++++"+Thread.CurrentThread.ManagedThreadId);
			if (receiveData.GetBuffer ().Length > 0 && clientSocket != null && clientSocket.Connected ) {
				
				MyConverter conver = new MyConverter (receiveData.GetBuffer());
				bool flag = true;
				int length = 0;

				while (flag) {

					if (conver.value.Length > 4) {

						length = conver.toInt32 ();

						if (length > 0) {
						
							Debug.Log ("这个消息长度:" + length + " 剩余字节长度" + conver.value.Length);
							if (conver.value.Length >= length) {
								byte[] msg = conver.copyByte (length);
								CoderFactory.DecodeByte (msg);
							} else {
								buffer = new ByteBuffer ();
								buffer.PushInt (length);
								buffer.PushByteArray (conver.value);
								flag = false;
							}

						} else {
							flag = false;
						}

					} else {
						if(conver.value.Length > 0){
							buffer = new ByteBuffer ();
							buffer.PushByteArray (conver.value);
						}

						flag = false;
					}
				}
				//用于做数据处理,加解密,或者压缩于解压缩
				prefixSize = 4;
				receiveData=new MemoryStream();
				isPresix = true;
				curPrefix = 0;//需要读取的数据总长度
			}
	    }	

		private static void SplitPackage(byte[] bytes,int length)
		{


		}

		public static void getDailyReward(){
			Send (ByteFactory.makeByte (202, null));
		}


		public static byte[] LittleToBig(string  str)
		{ return Encoding.BigEndianUnicode.GetBytes(str); }
		



		public static void Send(byte[] data){


			if (clientSocket != null ) {
				try{
					
					Debug.Log("消息发送,长度:"+data.Length);
					ByteTools.sendMsgCountAdd ();
					clientSocket.BeginSend (data, 0, data.Length, SocketFlags.None,new System.AsyncCallback (sendCallback), clientSocket);  
					
					
				}catch(SocketException io){
				
					Debug.Log("SOCKET发送消息失败 链接已经断开");
					connectioned = false;
				}
				
			} else {
				Debug.Log("SOCKET链接已经失效");
				connectioned = false;
			}
		}
	
		private static void sendCallback (IAsyncResult asyncSend)
		{
			Socket workingSocket = asyncSend.AsyncState as Socket;  
			workingSocket.EndSend (asyncSend); 
		}
		
		//关闭Socket
		public static void Closed()
		{
			
			if(clientSocket != null)
			{
				//thread.Abort ();
				clientSocket.Close();
			}
			connectioned = false;
			clientSocket = null;
		}



		void OnDestroy(){ 
			Debug.Log ("停止线程2");
			
		}
		
}
